package org.example.springai_deepseek.controller;

import lombok.extern.slf4j.Slf4j;
import org.example.springai_deepseek.utils.MyTools;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.client.advisor.api.AdvisedRequest;
import org.springframework.ai.chat.client.advisor.api.AdvisedResponse;
import org.springframework.ai.chat.client.advisor.api.Advisor;
import org.springframework.ai.chat.client.advisor.api.CallAroundAdvisorChain;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.function.FunctionToolCallback;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import java.util.Arrays;

/**
 * @author 沐雨栉风
 * @version 1.0
 * @description
 * @date 2025/2/28 18:33
 */
@RestController
@CrossOrigin("*")
@Slf4j
public class DeepSeekController {

    private final ChatClient chatClient;
    private final InMemoryChatMemory inMemoryChatMemory;

    private class MySimpleLoggerAdvisor extends SimpleLoggerAdvisor {
        @Override
        public AdvisedResponse aroundCall(AdvisedRequest advisedRequest, CallAroundAdvisorChain chain) {

            return super.aroundCall(advisedRequest, chain);
        }
    }

     //构造方法，用于构造chatclient 实例
    public DeepSeekController(ChatClient.Builder chatClientBuilder, InMemoryChatMemory inMemoryChatMemory) {
        this.inMemoryChatMemory = inMemoryChatMemory;
        // 设定系统提示词
        chatClientBuilder.defaultSystem("你现在在我的电脑上运行, 你可以通过我给的工具方法来达到我的目的, 可以分步骤进行, 如果是找文件方面但不明确路径, 例如桌面, 你需要先通过windows cmd获得桌面的路径, 在再进行下一步");
        chatClientBuilder.defaultAdvisors(new MySimpleLoggerAdvisor());
        this.chatClient = chatClientBuilder.build();
    }


    @GetMapping("/chat")
    public String chat(@RequestParam(value = "message") String message) {
        return chatClient.prompt(message)
                .tools(new MyTools())
                .call().content();
    }

    @RequestMapping(value = "stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> streamChat(@RequestBody ChatRequest request) {
        return chatClient.prompt(request.message)
                .system("当前你在本台电脑上运行, 你可以通过我给的工具方法来达到我的目的, 甚至可以分步骤进行最终达到目的即可")
                .tools(new MyTools())
                .stream().content().map(content -> ServerSentEvent.builder(content).event("message").build())
                //问题回答结速标识,以便前端消息展示处理
                .concatWithValues(ServerSentEvent.builder("[DONE]").build())
                .onErrorResume(e -> Flux.just(ServerSentEvent.builder("Error: " + e.getMessage()).event("error").build()));
    }

    /**
     * 开启记忆的聊天
     * @param request
     * @return
     */
    @PostMapping(value = "streamMemory", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> streamChatMemory(@RequestBody ChatRequest request) {
        //用户id
        String userId = request.userId();

        return chatClient.prompt(request.message())
                .advisors(new MessageChatMemoryAdvisor(inMemoryChatMemory, userId, 10), new SimpleLoggerAdvisor())
                .stream().content().map(content -> ServerSentEvent.builder(content).event("message").build())
                //问题回答结速标识,以便前端消息展示处理
                .concatWithValues(ServerSentEvent.builder("[DONE]").build())
                .onErrorResume(e -> Flux.just(ServerSentEvent.builder("Error: " + e.getMessage()).event("error").build()));
    }


    /**
     * 请求体
     * @param userId    用户ID，用于记忆对话内容
     * @param message   具体消息
     */
    record ChatRequest(String userId, String message) {

    }



}
